home *** CD-ROM | disk | FTP | other *** search
- ;
- ; string.s -- an ACE linked library module: string functions.
- ; Copyright (C) 1998 David Benn
- ;
- ; This program is free software; you can redistribute it and/or
- ; modify it under the terms of the GNU General Public License
- ; as published by the Free Software Foundation; either version 2
- ; of the License, or (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- ;
- ; Author: David J Benn
- ; Date: 3rd-30th November, 1st-13th December 1991,
- ; 20th, 23rd,25th-27th January 1992,
- ; 2nd,4th,6th,12th-19th,21st-24th,29th February 1992,
- ; 1st,14th March 1992,
- ; 4th,7th,21st,22nd,26th April 1992,
- ; 2nd,3rd,5th,7th,8th,10th-17th May 1992,
- ; 6th,8th,11th,12th,28th,30th June 1992,
- ; 1st-3rd,13th,14th,18th-20th,22nd July 1992,
- ; 9th August 1992,
- ; 5th,13th,29th,30th December 1992,
- ; 6th,12th January 1993,
- ; 7th,14th,16th,18th February 1993,
- ; 1st,14th March 1993,
- ; 9th,25th,30th May 1993,
- ; 6th,29th June 1993,
- ; 9th,11th October 1993,
- ; 19th March 1994,
- ; 12th,25th July 1994
- ;
- ; registers d0-d6 and a0-a3 are modified by some of the following. BEWARE!
- ;
- ; a4,a5 are used by link/unlk.
- ; a6 is library base holder.
- ; a7 is stack pointer.
- ; d7 is used for array index calculations.
- ;
-
- ; misc. defines
- MAXSTRINGSIZE equ 1024
- VANILLAKEY equ $00200000
- UserPort equ 86
-
- Class equ 0 ; member in IntuiInfo structure
- Code equ 4 ; member in IntuiInfo structure
- ; (see intuievent.h)
- pr_CLI equ 172
- cli_CommandName equ 16
-
- ; string functions
- xdef _htol
- xdef _leftstr
- xdef _rightstr
- xdef _midstr
- xdef _ucase
- xdef _inputstring
- xdef _hexstrlong
- xdef _hexstrshort
- xdef _octstr
- xdef _binstr
- xdef _strlong
- xdef _strshort
- xdef _inkey
- xdef _spacestring
- xdef _spc
- xdef _stringstr
- xdef _instr
-
- ; external references
- xref _strlen
- xref _strcpy
- xref _streq
-
- xref _shortfmt
- xref _longfmt
- xref _shorthexfmt
- xref _longhexfmt
- xref _zerostr
- xref _colonstr
-
- xref _tmpstring
- xref _deststraddr
- xref _count
- xref _ucasestring
- xref _spacestraddress
- xref _stringstraddress
- xref _octdigit
- xref _bindigit
- xref _inkeybuf
- xref _rawinpbuf
- xref _rawinpaddr
- xref _instrposn
- xref _search_offset
- xref _targetch
- xref _x_string
- xref _y_string
- xref _x_strlen
- xref _y_strlen
-
- xref _putchar
- xref _sprintf
- xref _strval
- xref _LVOSPFlt
- xref _LVOSPAdd
- xref _LVOSPDiv
- xref _LVOSPTst
- xref _LVOSPNeg
- xref _LVOWrite
- xref _LVORead
- xref _LVOWaitForChar
- xref _LVOExamine
- xref _LVOUnLock
- xref _DOSBase
- xref _MathBase
- xref _stdout
- xref _stdin
- xref _turncursoron
- xref _turncursoroff
- xref _AbsExecBase
- xref _LVOFindTask
- xref _Wdw
- xref _Wdw_id
- xref _IntuiMode
- xref _GetIntuiEvent
- xref _ClearIntuiEvent
-
- SECTION string_code,CODE
-
- ;*** STRING FUNCTIONS ***
-
- ;
- ; _htol - returns a LONG value in d0 from a HEX string pointed to by a1.
- ; _htol assumes that all digits are legal (1..9, a..f) and lowercase.
- ;
- _htol:
- moveq #0,d0
- _htoloop:
- cmpi.b #0,(a1)
- beq.s _quithtol ; EOS?
-
- cmpi.b #57,(a1)
- ble.s _decdigit ; <= 9 ?
-
- ; <= F -> hex digit
- move.b (a1)+,d1 ; hex digit
- ext.w d1
- ext.l d1
- sub.l #87,d1
- lsl.l #4,d0
- add.l d1,d0
-
- bra.s _htoloop
-
- _decdigit:
- move.b (a1)+,d1 ; decimal digit
- ext.w d1
- ext.l d1
- sub.l #48,d1
- lsl.l #4,d0
- add.l d1,d0
-
- bra.s _htoloop
- _quithtol:
- rts
-
- ;
- ; LEFT$ function. expects string address in a0, sub-string address in a1
- ; and index in d0 (SHORT).
- ; returns address of sub-string in a0.
- ;
- _leftstr:
- move.l a1,a3 ; save address of target sub-string
- _leftstrloop:
- cmpi.w #0,d0 ; transfered n bytes?
- ble.s _leftstrquit
- cmpi.b #0,(a0) ; EOS?
- beq.s _leftstrquit
- move.b (a0)+,(a1)+ ; copy a byte
- subq #1,d0
- bra.s _leftstrloop
- _leftstrquit:
- move.b #0,(a1)
- move.l a3,a0 ; return address of sub-string
- rts
-
- ;
- ; RIGHT$ function. expects string address in a0, sub-string address in a1
- ; and index in d0 (SHORT).
- ; returns address of sub-string in a0.
- ;
- _rightstr:
- move.l a1,a3 ; get address of target sub-string
- move.w d0,d1 ; save length of sub-string
- cmpi.w #0,d0
- ble.s _rightstrquit ; return NULL string if requested length <= 0
- move.l a0,a2
- jsr _strlen ; d0 = length of string pointed to by a2
- ext.l d1
- sub.l d1,d0 ; starting position = strlen-index
- cmpi.l #0,d0
- bgt.s _rightstrpoint ; index < strlen(string) -> okay
- moveq #0,d0 ; index >= strlen(string) so return whole string
- _rightstrpoint:
- add.l d0,a0 ; point to it
- _rightstrloop:
- cmpi.b #0,(a0) ; EOS?
- beq.s _rightstrquit
- move.b (a0)+,(a1)+ ; copy a byte
- subq #1,d0
- bra.s _rightstrloop
- _rightstrquit:
- move.b #0,(a1)
- move.l a3,a0 ; address of sub-string
- rts
-
- ;
- ; MID$ function. Expects string address in a0, sub-string address in a1,
- ; start posn in d0 and length of sub-string in d1 (both SHORT).
- ; returns address of sub-string in a0.
- ;
- ; MID$(X$,n[,m]) -> a0=X$,d0=n,d1=m
- ;
- _midstr:
- move.l a1,a3 ; save address of target sub-string
- move.w d0,d2 ; save start position (n)
- move.l a0,a2
- jsr _strlen ; d0 = length of string pointed to by a2
- cmpi.w #-1,d1
- bne.s _midstr1
- move.w d0,d1 ; if m is -1 -> take FULL length of string
- _midstr1:
- ext.l d2
- cmp.l d0,d2
- bgt.s _midstrquit ; n > strlen(string)? -> quit
- cmpi.w #0,d1
- bge.s _midstrpoint ; negative? -> make zero
- moveq #0,d1
- _midstrpoint:
- add.l d2,a0 ; start at nth character
- subq #1,a0
- _midstrloop:
- cmpi.w #0,d1
- beq.s _midstrquit ; m characters copied?
- cmpi.b #0,(a0)
- beq.s _midstrquit ; EOS?
- move.b (a0)+,(a1)+ ; copy a byte
- subq #1,d1
- bra.s _midstrloop
- _midstrquit:
- move.b #0,(a1)
- move.l a3,a0 ; return sub-string address
- rts
-
- ;
- ; UCASE$ - Convert lower case characters in string (a1) to upper case.
- ; - Destination string in a0.
- ;
- _ucase:
- ; store destination address
- move.l a0,_ucasestring
-
- ; make a copy
- jsr _strcpy
-
- ; main loop
- movea.l _ucasestring,a1
- _ucaseloop:
- cmpi.b #0,(a1)
- beq.s _ucaseexit ; EOS?
- cmpi.b #97,(a1)
- blt.s _nextchar ; (a0) < 'a'?
- cmpi.b #122,(a1)
- bgt.s _nextchar ; (a0) > 'z'?
- sub.b #32,(a1) ; 'a'..'z' -> make 'A'..'Z'
- _nextchar:
- addq #1,a1
- bra.s _ucaseloop
- _ucaseexit:
- movea.l _ucasestring,a0
- rts
-
- ;
- ; get a string from _stdin and return it's address in a0.
- ; expects target string address in a1.
- ;
- _inputstring:
- move.l a1,a3 ; save input string address
-
- jsr _turncursoron
-
- ; get the string
- cmpi.w #0,_Wdw_id
- beq.s _inputconstring ; if Wdw-id = 0 then window is CON:
- jsr _inputrawstring ; if Wdw-id <> 0 then window is RAW:
- bra.s _exitinputstring
-
- _inputconstring:
- move.l _DOSBase,a6
- move.l _stdin,d1
- move.l a3,d2 ; get start address of input string
- move.l #MAXSTRINGSIZE-1,d3; allow the max string size. d0=actual.
- jsr _LVORead(a6)
- move.l a3,a0
- subq #1,d0
- clr.b 0(a0,d0) ; append EOS character
-
- _exitinputstring:
- jsr _turncursoroff
-
- move.l a3,a0 ; restore start address of input string
-
- rts
-
- ;
- ; INPUT a string from a RAW: window. a3 points to input string.
- ; Destructive backspace (ASCII 8) is handled as expected, while
- ; all other characters are passed into the final string.
- ;
- _inputrawstring:
- move.l a3,_rawinpaddr ; save the address
-
- _waitforinput:
- move.l _DOSBase,a6
- move.l _stdin,d1
- moveq #1,d2
- jsr _LVOWaitForChar(a6)
- cmpi.w #0,d0
- beq.s _waitforinput
-
- ; get pending character
- move.l _DOSBase,a6
- move.l _stdin,d1
- move.l #_rawinpbuf,d2 ; address of buffer
- moveq #1,d3
- jsr _LVORead(a6) ; read 1 character
-
- ; is it a destructive backspace?
- cmpi.b #8,_rawinpbuf
- bne.s _displayrawchar ; no -> just display it
-
- ; BS: are we back at the start of the line?
- cmpa.l _rawinpaddr,a3
- beq.s _waitforinput ; yes -> can't delete any more!
-
- _displayrawchar:
- move.l _DOSBase,a6
- move.l _stdout,d1
- move.l #_rawinpbuf,d2
- moveq #1,d3
- jsr _LVOWrite(a6) ; display character
-
- ; is it a destructive backspace?
- cmpi.b #8,_rawinpbuf
- bne.s _addchartostring ; not BS, so keep it
-
- ; delete last character
- suba.l #1,a3 ; otherwise, move back one character
-
- move.l _DOSBase,a6
- move.l _stdout,d1
- move.b #32,_rawinpbuf
- move.l #_rawinpbuf,d2
- moveq #1,d3
- jsr _LVOWrite(a6) ; write a space over last character
-
- move.l _DOSBase,a6
- move.l _stdout,d1
- move.b #8,_rawinpbuf
- move.l #_rawinpbuf,d2
- moveq #1,d3
- jsr _LVOWrite(a6) ; move back to "wiped-out" character
-
- bra _waitforinput ; then wait for next character
-
- _addchartostring:
- ; add to string
- cmpi.b #13,_rawinpbuf ; carriage return? -> EOS
- beq.s _exitrawinput
-
- move.b _rawinpbuf,(a3)+ ; add character to string
-
- bra _waitforinput ; wait for next character
-
- _exitrawinput:
- move.b #0,(a3)
- move.l _rawinpaddr,a3 ; address of string
-
- move.l #10,-(sp)
- jsr _putchar ; Line Feed
- addq #4,sp
-
- rts
-
- ;
- ; HEX$ - returns hexadecimal string form (a0) of short decimal value (d0).
- ;
- _hexstrshort:
- move.l a0,a3 ; save destination string address
- move.w d0,-(sp) ; push short value
- pea _shorthexfmt ; push format string
- move.l a0,-(sp) ; push destination string
- jsr _sprintf
- add.l #10,sp
- move.l a3,a0 ; restore destination string address
- rts
- ;
- ; HEX$ - returns hexadecimal string form (a0) of long decimal value (d0).
- ;
- _hexstrlong:
- move.l a0,a3 ; save destination string address
- move.l d0,-(sp) ; push long value
- pea _longhexfmt ; push format string
- move.l a0,-(sp) ; push destination string
- jsr _sprintf
- add.l #12,sp
- move.l a3,a0 ; restore destination string address
- rts
- ;
- ; OCT$ - returns octal string form (a0) of long decimal value (d0).
- ;
- _octstr:
- move.l a0,a3 ; save address of dest string
-
- ; if zero, make a string with 1 digit: "0"
- cmpi.l #0,d0
- bne.s _octnotzero
- move.b #48,(a0)+ ; string[0]='0'
- move.b #0,(a0) ; EOS
- movea.l a3,a0
- rts
-
- _octnotzero:
- move.w #0,d2 ; cc=0
- lea _octdigit,a0
-
- _octloop:
- cmpi.l #0,d0
- beq.s _reversedigits ; until num == 0
-
- ; get remainder
- move.l d0,d1 ; num
- move.l d0,d3
- lsr.l #3,d3 ; num\8
- lsl.l #3,d3 ; quotient*8
- sub.l d3,d1 ; r=num-(quotient*8) = num % 8
-
- add.l #48,d1 ; ASCII = 48 + d1
- and.b #$ff,d1
- move.b d1,(a0)+ ; x[cc]=r
- addi.w #1,d2 ; cc++ (keep count of characters)
-
- lsr.l #3,d0 ; num \= 8
-
- bra.s _octloop
-
- _reversedigits:
- move.l a3,a1 ; string address
-
- _makeoctstring:
- cmpi.w #0,d2
- ble.s _stripoctzeros ; while cc > 0
-
- subi.w #1,d2 ; --cc
- move.b -(a0),(a1)+ ; string[cc] = x[cc]
-
- bra.s _makeoctstring
-
- _stripoctzeros:
- move.b #0,(a1) ; EOS
- move.l a3,a1 ; start of string
-
- _octstriploop:
- ; strip leading zeros
- cmpi.b #0,(a1)
- beq.s _exitoctstr ; exit if EOS (null string?)
-
- cmpi.b #48,(a1)
- bgt.s _exitoctstr ; digit > 0? -> exit
-
- adda.l #1,a1
-
- bra.s _octstriploop
-
- _exitoctstr:
- move.l a1,a0 ; return destination string address
- rts
-
- ;
- ; STR$ - returns string form (a0) of short decimal value (d0).
- ;
- _strshort:
- move.l a0,a3 ; save destination string address
- cmpi.w #0,d0
- blt.s _strshortdo ; is value >= 0?
- move.b #32,(a0)+ ; yes -> leading space
- _strshortdo:
- move.w d0,-(sp) ; push short value
- pea _shortfmt ; push format string
- move.l a0,-(sp) ; push destination string
- jsr _sprintf
- add.l #10,sp
- move.l a3,a0 ; restore destination string address
- rts
-
- ;
- ; STR$ - returns string form (a0) of long decimal value (d0).
- ;
- _strlong:
- move.l a0,a3 ; save destination string address
- move.l a0,a3 ; save destination string address
- cmpi.l #0,d0
- blt.s _strlongdo ; is value >= 0?
- move.b #32,(a0)+ ; yes -> leading space
- _strlongdo:
- move.l d0,-(sp) ; push long value
- pea _longfmt ; push format string
- move.l a0,-(sp) ; push destination string
- jsr _sprintf
- add.l #12,sp
- move.l a3,a0 ; restore destination string address
- rts
-
- ;
- ; INKEY$ - returns a single character string (address in d0) from stdin if
- ; a character is pending or the NULL string if not. If IntuiMode
- ; is 1, the Window's IDCMP port is checked for a VANILLAKEY event.
- ;
- _inkey:
- cmpi.b #0,_IntuiMode
- beq _stdinkey
-
- ; check for Intuition event
- movea.l _Wdw,a0
- move.l UserPort(a0),-(sp) ; get window's UserPort (Wdw->UserPort)
- jsr _GetIntuiEvent
- addq #4,sp
-
- tst.l d0
- bne.s _checkforkey ; an event took place!
- bra.s _quitintuiinkey ; no event took place
-
- _checkforkey:
- movea.l d0,a0 ; pointer to IntuiInfo structure
-
- move.l Class(a0),d1 ; Message->Class
- andi.l #VANILLAKEY,d1
- cmpi.l #VANILLAKEY,d1
- beq.s _getvanillakey
-
- ; no vanilla key event -> quit
- bra.s _quitintuiinkey
-
- _getvanillakey:
- ; there's a vanilla key event
- move.w Code(a0),d1 ; Message->Code
- andi.b #$ff,d1
-
- ; construct string
- movea.l #_inkeybuf,a0
- move.b d1,(a0)+
- move.b #0,(a0)
-
- ; reply to message
- jsr _ClearIntuiEvent
-
- ; return address of string
- move.l #_inkeybuf,d0
-
- rts
-
- _quitintuiinkey:
- ; no event or no vanilla key -> return NULL string
- movea.l #_inkeybuf,a0
- move.b #0,(a0)
-
- move.l #_inkeybuf,d0 ; return address of string
-
- rts
-
- _stdinkey:
- move.l _DOSBase,a6
-
- ; check for pending character(s)
- move.l _stdin,d1
- moveq #1,d2 ; wait 1 microsecond
- jsr _LVOWaitForChar(a6)
- cmpi.w #0,d0
- bne.s _readinkey
-
- move.l #_inkeybuf,a0
- move.b #0,(a0) ; NULL string
-
- move.l #_inkeybuf,d0 ; return address of string
-
- rts
-
- _readinkey:
- ; read one character
- move.l _stdin,d1
- move.l #_inkeybuf,d2
- moveq #1,d3
- jsr _LVORead(a6)
-
- move.l #_inkeybuf,a0
- addq #1,a0
- move.b #0,(a0) ; EOS
-
- move.l #_inkeybuf,d0 ; return address of string
-
- rts
-
- ;
- ; SPACE$(n) - returns the address of a string (in d0) with n spaces. d0=n.
- ; - destination string address in a0.
- ;
- _spacestring:
- move.l a0,_spacestraddress
-
- cmpi.w #0,d0
- ble.s _quitspacestring ; n <= 0 -> quit
-
- cmpi.w #MAXSTRINGSIZE,d0
- blt.s _buildspacestring
- move.w #MAXSTRINGSIZE-1,d0 ; n >= MAXSTRINGSIZE -> clip
-
- _buildspacestring:
- move.b #32,(a0)+
- subq.w #1,d0
- cmpi.w #0,d0
- bgt.s _buildspacestring
-
- _quitspacestring:
- move.b #0,(a0)
- move.l _spacestraddress,d0
-
- rts
-
- ;
- ; SPC(n) - returns the address of a string (in d0) with n spaces. d0=n.
- ; - destination string address in a0.
- ;
- _spc:
- move.l a0,_spacestraddress
-
- cmpi.w #0,d0
- ble.s _quitspcstring ; n <= 0 -> quit
-
- cmpi.w #255,d0
- blt.s _buildspcstring
- move.w #255,d0 ; n >= MAXSTRINGSIZE -> clip
-
- _buildspcstring:
- move.b #32,(a0)+
- subq.w #1,d0
- cmpi.w #0,d0
- bgt.s _buildspcstring
-
- _quitspcstring:
- move.b #0,(a0)
- move.l _spacestraddress,d0
-
- rts
-
- ;
- ; STRING$(n,m) - returns the address of a string (in d0) with n characters
- ; of ASCII value m. d0=n, d1=m.
- ; - destination string address in a0.
- ;
- _stringstr:
- move.l a0,_stringstraddress
-
- cmpi.w #0,d0
- ble.s _quitstringstr ; n <= 0 -> quit
-
- cmpi.w #MAXSTRINGSIZE,d0
- blt.s _buildstringstr
- move.w #MAXSTRINGSIZE-1,d0 ; n >= MAXSTRINGSIZE -> clip
-
- _buildstringstr:
- move.b d1,(a0)+
- subq.w #1,d0
- cmpi.w #0,d0
- bgt.s _buildstringstr
-
- _quitstringstr:
- move.b #0,(a0)
- move.l _stringstraddress,d0
-
- rts
-
- ;
- ; INSTR([I,],X$,Y$) - returns the first occurrence of Y$ in X$.
- ; - the search starts from MID$(X$,I,1).
- ; - if I is not specified, it takes on a value of 1.
- ; - the result is returned in d0.
- ; - d0=I, a0=X$, a1=Y$.
- ;
- _instr:
- ; result in case of error
- move.l #0,_instrposn
-
- ; store the parameters
- move.l d0,_search_offset ; I
- move.l a0,_x_string ; X$
- move.l a1,_y_string ; Y$
- move.b (a1),_targetch ; first character of Y$
-
- ; is I < 1 ?
- cmpi.l #1,_search_offset
- blt _quitinstr ; I <= 0 -> result=0
-
- ; find length of X$
- movea.l _x_string,a2
- jsr _strlen
- move.l d0,_x_strlen
-
- ; is X$="" ?
- cmpi.l #0,d0
- beq _quitinstr ; X$="" -> result=0
-
- ; is I > len(X$) ?
- move.l _search_offset,d1
- cmp.l d0,d1
- bgt _quitinstr ; I > LEN(X$) -> result=0
-
- ; find length of Y$
- movea.l _y_string,a2
- jsr _strlen
- move.l d0,_y_strlen
-
- ; is len(Y$) > len(X$) ?
- move.l _x_strlen,d0
- move.l _y_strlen,d1
- cmp.l d0,d1
- bgt _quitinstr ; len(Y$) > len(X$) -> result=0
-
- ; is Y$="" ?
- cmpi.l #0,_y_strlen
- bne.s _search_x_for_y
-
- move.l _search_offset,_instrposn
- bra.s _quitinstr ; Y$="" -> result=I
-
- _search_x_for_y:
- ; compare first character only
- movea.l _x_string,a0 ; A=address of first character in X$
- adda.l _search_offset,a0 ; A=A+I
- suba.l #1,a0 ; A=A+I-1 (adjust to start at 0th byte)
- move.b (a0),d0
- move.b _targetch,d1 ; get first character from Y$
- cmp.b d0,d1
- beq.s _check_whole_string ; first characters match
- bra.s _inc_search_offset ; try next character
-
- _check_whole_string:
- ; get MID$(X$,I,len(Y$))
- movea.l _x_string,a0
- lea _tmpstring,a1
- move.l _search_offset,d0
- move.l _y_strlen,d1
- jsr _midstr ; a0 = MID$(X$,I,len(Y$)) -> _streq
-
- ; is MID$(X$,I,len(Y$)) = Y$ ?
- movea.l _y_string,a1
- jsr _streq
- cmpi.l #0,d0
- beq.s _inc_search_offset ; MID$(X$,I,len(Y$)) <> Y$ -> ++I
-
- ; found it!
- move.l _search_offset,_instrposn
- bra.s _quitinstr
-
- _inc_search_offset:
- add.l #1,_search_offset
- move.l _x_strlen,d0
- move.l _search_offset,d1
- cmp.l d0,d1
- ble.s _search_x_for_y
-
- _quitinstr:
- move.l _instrposn,d0
-
- rts
-
- ;
- ; BIN$ - returns binary string form (a0) of long decimal value (d0).
- ;
- _binstr:
- move.l a0,a3 ; save address of dest string
-
- ; if zero, make a string with 1 digit: "0"
- cmpi.l #0,d0
- bne.s _binnotzero
- move.b #48,(a0)+ ; string[0]='0'
- move.b #0,(a0) ; EOS
- movea.l a3,a0
- rts
-
- _binnotzero:
- move.w #0,d2 ; cc=0
- lea _bindigit,a0
-
- _binloop:
- cmpi.l #0,d0
- beq.s _revdigits ; until num == 0
-
- ; get remainder
- move.l d0,d1 ; num
- move.l d0,d3
- lsr.l #1,d3 ; num\2
- lsl.l #1,d3 ; quotient*2
- sub.l d3,d1 ; r=num-(quotient*2) = num % 2
-
- add.l #48,d1 ; ASCII = 48 + d1
- and.b #$ff,d1
- move.b d1,(a0)+ ; x[cc]=r
- addi.w #1,d2 ; cc++ (keep count of characters)
-
- lsr.l #1,d0 ; num \= 2
-
- bra.s _binloop
-
- _revdigits:
- move.l a3,a1 ; string address
-
- _makebinstring:
- cmpi.w #0,d2
- ble.s _stripbinzeros ; while cc > 0
-
- subi.w #1,d2 ; --cc
- move.b -(a0),(a1)+ ; string[cc] = x[cc]
-
- bra.s _makebinstring
-
- _stripbinzeros:
- move.b #0,(a1) ; EOS
- move.l a3,a1 ; start of string
-
- _binstriploop:
- ; strip leading zeros
- cmpi.b #0,(a1)
- beq.s _exitbinstr ; exit if EOS (null string?)
-
- cmpi.b #48,(a1)
- bgt.s _exitbinstr ; digit > 0? -> exit
-
- adda.l #1,a1
-
- bra.s _binstriploop
-
- _exitbinstr:
- move.l a1,a0 ; return destination string address
- rts
-
- END
-